package orbito.scene;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.List;
import java.util.Random;

import orbito.graphics.ViewFocus;
import orbito.graphics.MessageQueue;
import orbito.graphics.View;
import orbito.graphics.Viewport;

public interface SceneGraph {
	/**
	 * Initializes the scene. When called, should initialize, or re-initialize, the scene.
	 * 
	 * @param rand     The randomizer that should be used to deterministically create the scene.
	 * @param messages The messages queue that should be used to output messages on-screen.
	 */
	void init(Random rand, MessageQueue messages);
	
	/**
	 * Performs a scene step. When called, should perform a step in the scene, advancing 
	 * all states from sim-time t to sim-time t+dt.
	 * 
	 * @param t  The current sim-time of the scene.
	 * @param dt The sim-time that is expected to pass during this step, in seconds.
	 */
	void step(double t, double dt);
	
	/**
	 * Renders the scene. When called, should render the scene to the given graphics 
	 * context as it appears at sim-time t.
	 * 
	 * @param g  The graphics context.
	 * @param t  The current sim-time of the scene, in seconds.
	 * @param dt The real-time since last render, in seconds.
	 */
	void render(Graphics2D g, double t, double dt);
	
	/**
	 * Renders the scene info, if any. When called, should render information about the scene.
	 * 
	 * @param g  The graphics context.
	 * @param v  The current viewport.
	 * @param tx The view transform.
	 * @param t  The sim-time of the scene, in seconds.
	 * @param dt The real-time since last render, in seconds.
	 */
	void renderInfo(Graphics2D g, Viewport v, AffineTransform tx, double t, double dt);

	/**
	 * Handles time-dependent user input. When called, should handle user input to interact with the scene.
	 * 
	 * @param dt The real-time passed since the last time input was handled, in seconds.
	 */
	void handleInput(double dt);
	
	/**
	 * Gets the available views in the scene. When called, should return the views currently available in the scene.
	 * 
	 * @return The views in the scene.
	 */
	List<View> getViews();
	
	/**
	 * Gets the current view in the scene. When called, should return the view currently used in the scene.
	 * 
	 * @return The current view in the scene.
	 */
	View getCurrentView();
	
	/**
	 * Sets the current view in the scene. When called, should set the current view used in the scene.
	 * 
	 * @param view The new current view in the scene.
	 */
	void setCurrentView(View view);
	
	/**
	 * Gets the collection of objects in the scene that can be focused on by the view/camera.
	 * 
	 * @return The collection of view focus items.
	 */
	List<ViewFocus> getViewFocusItems();
	
	/**
	 * Gets the name of the scene.
	 * 
	 * @return The name of the scene.
	 */
	String getSceneName();
}
